#include "REG51.h"
#include "lcd_init.h"
#include "lcd.h"
#include "GUI.H"
#include "string.h"
//#include "pic.h"

#define FORAVGE(A, B, i) (A + ((B - A) / (1 + i)))

xdata TL_DB[18] = {0xe0, 0xc0, 0x60, 0xc0, 0x80, 0xc0, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
xdata TH_DB[18] = {0xff, 0xff, 0xff, 0xfe, 0xfd, 0xf9, 0xf3, 0xf7, 0xc1, 0x83, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
xdata range_db[3] = {1, 2, 5};
xdata u8 p[] = "DSO By Eltecz";
void adc_init(u8 ch);

u8 getadc();
u8 db[adc_length * 3];
u8 screen_db[adc_length];
u8 screen_db_old[adc_length];
u8 *padc = &db[0];

u16 adc_length2_5 = adc_length * 2.5;
u16 adc_length3 = adc_length * 3;
extern gui_dev guidev;
extern u8 en_adc;
void Timer0Init(void); //200微秒@32MHz
u8 key_scan();
u8 abs(int a, u8 max)
{
	if (a > max)
		return max;
	else if (a < 0)
		return 0;
	else
		return a;
}
int main(void)
{
	u16 ff1, ff2;
	u16 preff1;
	u16 i;
	u8 div = 7;
	u8 tim = 0;
	u8 trig_1 = 0;
	u16 lens = 0;
	u16 but;
	u8 swap = 0;
	u8 key_arvg = 0;
	u8 keydown;
	u8 *padc_screen_db;
	u8 *padc_screen_olddb;
	P3M0 = 0x0b;
	P3M1 = 0x02;
	P5M0 = 0x10;
	P5M1 = 0x20;
	LCD_CS = 0;
	LCD_Init(); //LCD初始化
	memset(screen_db_old, 0, 128);
	gui_init();
	LCD_Fill(0, 0, LCD_W, LCD_H, BLACK);

	EA = 1;
	while (1)
	{
		LCD_ShowString(0, 68, p, (key_arvg > 100) ? YELLOW : GRAY, BLACK, 0);
		swap++;
		lens = keydown = 0;
		adc_init(5);
		Timer0Init();
		TR0 = 1; //定时器0开始计时
		for (i = 0; i < adc_length * 3; i++)
		{
			ADC_CONTR |= 0x40;
			while (!(ADC_CONTR & 0x20))
				; //查询ADC完成标志

			ADC_CONTR &= ~0x20; //清完成标志
			*(padc + i) = ADC_RES;
			//					ADC_CONTR += 0x20;                          //启动AD转换

			//				P55=!P55;
			//			TF0=0;
			en_adc = 1;
			while (en_adc)
				;
		}

		TR0 = 0; //定时器0开始计时
				 //			  ET0 = 0;                                    //使能定时器中断
		i = adc_length / 2;
		if (guidev.trig)
		{
			while ((i < adc_length2_5))
			{
				if ((((guidev.trig - 1) ? (db[i] >= (guidev.trig32) && db[i - 1] < (guidev.trig32)) : ((db[i] <= guidev.trig32) && db[i - 1] > (guidev.trig32)))) == 1)
				{

					if ((i > (ff1 + adc_length)))
					{
						break;
					}
					else if (lens)
					{
						ff2 = i;
					}
					else
					{
						guidev.mw = i;
						ff1 = i;
					}
					lens++;
				}
				i++;
			}
			lens--;
		}
		if (guidev.mw == 0)
		{
			guidev.mw = adc_length * 0.5;
			guidev.freq = 0;
		}
		else if ((ff2 - ff1))
		{

			guidev.freq = (1000000 / (ff2 - ff1)) * lens;
		}
		else
		{
			guidev.freq = 1000000 * lens;
		}

		//		LCD_ShowIntNum(0,66,padc_screen_olddb,5,RED,BLACK);

		if (swap % 2)
		{
			padc_screen_db = &screen_db[0];
			padc_screen_olddb = &screen_db_old[0];
		}
		else
		{
			padc_screen_db = &screen_db_old[0];
			padc_screen_olddb = &screen_db[0];
		}
		*padc = &db[ff1 - adc_length / 2];
		//	swap(padc_screen_db,padc_screen_olddb);
		for (i = 0; i < adc_length; i++)
		{
			guidev.sum += (*(padc + i));
			if ((*(padc + i) > guidev.max_vote))
			{
				guidev.max_vote = *(padc + i);
			}
			if ((guidev.min_vote > *(padc + i)))
			{
				guidev.min_vote = *(padc + i);
			}
			*(padc_screen_db + i) = guidev.high - abs((u16)((db[ff1 - adc_length / 2 + i]) * range_db[guidev.div]) * guidev.high >> 8, guidev.high);
		}
		*padc = &db[0];
		LCD_ShowIntNum(120, 0, range_db[guidev.div], 4, guidev.div_color, BLACK);
		LCD_ShowChar(144, 0, 'X', guidev.div_color, BLACK, 0);
		keydown = key_scan();

		if (keydown)
		{
			delay_ms(100);
			if (key_arvg < 10)
			{
				switch (keydown)
				{
				case 1:
					key_arvg += (key_arvg == 4) ? -4 : 1;
					break;
				case 2:
					key_arvg += 100;
					break;
				case 3:
					key_arvg -= (key_arvg) ? 1 : -4;
					break;
				}
			}
			else
			{
				if (keydown == 2)
					key_arvg -= 100;
				switch (key_arvg % 10)
				{
				case 1:
					switch (keydown)
					{
					case 1:
						guidev.trig += (guidev.trig == 2) ? -2 : 1;
						break;
					case 3:
						guidev.trig -= (guidev.trig) ? 1 : -2;
						break;
					}
					break;
				case 2:
					switch (keydown)
					{
					case 1:
						guidev.trig_level += (guidev.trig_level == 9) ? -8 : 1;
						break;
					case 3:
						guidev.trig_level -= (guidev.trig_level == 1) ? -8 : 1;
						break;
					}

					guidev.trig_levelf = guidev.trig_level / 10.0;
					guidev.trig32 = (u8)(guidev.trig_levelf * 256);
					break;
				case 3:
					switch (keydown)
					{
					case 1:
						guidev.timer += (guidev.timer == 10) ? -9 : 1;
						break;
					case 3:
						guidev.timer -= (guidev.timer == 1) ? -9 : 1;
						break;
					}
					break;
				case 4:
					switch (keydown)
					{
					case 1:
						guidev.div += (guidev.div == 2) ? -2 : 1;
						break;
					case 3:
						guidev.div -= (guidev.div) ? 1 : -2;
						break;
					}
					break;
				}
				LCD_Fill(0, 0, LCD_W, LCD_H, BLACK);
			}
			guidev.trig_mode_color = (key_arvg % 10 == 1) ? 0XFFFF - trig_way_col : trig_way_col;
			guidev.trig_level_color = (key_arvg % 10 == 2) ? 0XFFFF - trig_col : trig_col;
			guidev.time_level_color = (key_arvg % 10 == 3) ? 0XFFFF - time_col : time_col;
			guidev.div_color = (key_arvg % 10 == 4) ? 0XFFFF - div_col : div_col;
		}
		draw_gui(padc_screen_db, padc_screen_olddb);
		but = 0;
		gui_ref();
	}
}
void adc_init(u8 ch)
{
	ADC_CONTR = 0;
	ADC_RES = 0;
	ADC_RESL = 0;
	ADC_CONTR = 0Xc0 | (ch);
	ADCTIM = 11;

	ADCCFG = 0;
}

u8 getadc()
{

	ADC_CONTR |= 0x40; //启动AD转换
	while (!(ADC_CONTR & 0x20))
		;				//查询ADC完成标志
	ADC_CONTR &= ~0x20; //清完成标志
						//	delay_us(time);
						//	ADC_CONTR &= ~1;                    //关闭ADC
	return ADC_RES;
}
void Timer0Init(void) //200微秒@32MHz
{
	AUXR |= 0x80;			   //定时器时钟1T模式
	TMOD &= 0xF0;			   //设置定时器模式
	TL0 = TL_DB[guidev.timer]; //设置定时初始值
	TH0 = TH_DB[guidev.timer];

	ET0 = 1; //使能定时器中断
	EA = 1;
	//
}
void TM0_Isr() interrupt 1
{
	en_adc = 0;
}
u8 key_scan()
{
	u8 key_adcs = 0;
	u16 adcdb;
	adc_init(1);
	delay_ms(1);
	adcdb = (getadc() + getadc() + getadc() + getadc()) / 4;

	if (adcdb < 128)
		return 3;
	else if (adcdb < 200)
		return 2;
	else if (adcdb < 230)
		return 1;
	else
		return 0;
}